package com.woniu108.extra.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu108.carService.commos.dto.OrderStreamDto;
import com.woniu108.carService.commos.dto.StoreDto;
import com.woniu108.carService.commos.dto.UserInfoDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.JWTUtil;
import com.woniu108.carService.commos.util.RedisUtil;
import com.woniu108.carService.commos.util.StaticData;
import com.woniu108.extra.client.OrderClient;
import com.woniu108.extra.client.PersonClient;
import com.woniu108.extra.form.OrderStreamFilterForm;
import com.woniu108.extra.model.OrderStream;
import com.woniu108.extra.model.Stream;
import com.woniu108.extra.model.StreamInfo;
import com.woniu108.extra.param.OrderStreamFilterParam;
import com.woniu108.extra.service.OrderStreamService;
import com.woniu108.extra.service.StreamInfoService;
import com.woniu108.extra.service.StreamService;
import com.woniu108.order.model.dto.OrderServiceDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单流程表 前端控制器
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@RestController
@RequestMapping("/orderStream")
@Api(tags = "订单流程管理接口")
public class OrderStreamController {

    @Resource
    private StreamService streamService;
    @Resource
    private OrderStreamService orderStreamService;
    @Resource
    private StreamInfoService streamInfoService;
    @Resource
    private PersonClient personClient;
    @Resource
    private OrderClient orderClient;
    @Resource
    private RedisUtil redisUtil;

    public String getStoreAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String storeAdminId= JWTUtil.parseStoreAdminToken(refreshToken).get("storeAdminId").toString();
        return storeAdminId;
    }
    public String getAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String adminId= JWTUtil.parseAdminToken(refreshToken).get("adminId").toString();
        return adminId;
    }

    /**
     * 生成用户订单流程信息
     * @param orderServiceNum 服务订单编号
     * @param userId 用户编号
     * @param storeId 门店编号
     * @param streamId 服务流程Id
     * @return result 是否正常访问接口结果
     */
    @GetMapping("/addOrderStream.api")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderServiceNum",value = "服务订单编号"),
            @ApiImplicitParam(name = "userId",value = "用户编号"),
            @ApiImplicitParam(name = "storeId",value = "门店编号"),
            @ApiImplicitParam(name = "streamId",value = "服务流程Id")
    })
    @ApiOperation("生成用户订单流程信息")
    public Result addOrderStream(String orderServiceNum,String userId,Integer storeId,Integer streamId,Integer serviceId){
        //查询对应流程是否存在，流程目前是否可用
        Stream stream = streamService.getById(streamId);
        if(ObjectUtil.isEmpty(stream)||stream.getStreamState()!= StaticData.STREAM_STATE_NORMAL) throw new WoniuException("流程模板状态异常",10001);
        //判断用户是否正常,门店是否正常,订单信息是否处于流程初始状态
        Result<UserInfoDto> result = personClient.getByUserId(userId);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        Result<StoreDto> result1 = personClient.getStoreById(storeId);
        if(result1.getCode()!=200) throw new WoniuException(result1.getMsg(),result1.getCode());
        Result<OrderServiceDto> result2 = orderClient.queryOrderServiceByOrderServiceNum(orderServiceNum);
        if(result2.getCode()!=200) throw new WoniuException(result2.getMsg(),result2.getCode());
        //若存在，根据流程模板内的详细信息构成用户订单流程
        QueryWrapper<StreamInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("stream_id",streamId);
        List<StreamInfo> streamInfos = streamInfoService.list(wrapper);
        for (StreamInfo streamInfo : streamInfos) {
            OrderStream orderStream = new OrderStream();
            orderStream.setStreamId(streamId);
            orderStream.setStreamInfoId(streamInfo.getStreamInfoId());
            orderStream.setOrderServiceNum(orderServiceNum);
            orderStream.setOrderStreamState2(StaticData.ORDER_STREAM_STATE_NORMAL);
            orderStream.setStoreId(storeId);
            orderStream.setUserId(userId);
            orderStream.setServiceId(serviceId);
            orderStreamService.save(orderStream);
        }
        return Result.getResult().setMsg("新增用户订单流程成功");
    }

    /**
     * 获取单个订单的订单流程详细信息
     * @param orderServiceNum 服务订单编号
     * @return List<OrderStreamDto> 指定的订单流程详细信息列表
     */
    @GetMapping("/getOrderStreamByNum/{orderServiceNum}.c")
    @ApiOperation("获取指定用户订单的流程详细信息")
    @ApiImplicitParam(name = "orderServiceNum", value = "服务订单编号")
    public Result<List<OrderStreamDto>> getOrderStreamByNum(String orderServiceNum){
        QueryWrapper<OrderStream> wrapper=new QueryWrapper<>();
        wrapper.eq("order_service_num",orderServiceNum);
        List<OrderStream> list = orderStreamService.list(wrapper);
        if(ObjectUtil.isEmpty(list)) throw new WoniuException("订单信息不存在",10001);
        List<OrderStreamDto> dtos=new ArrayList<>();
        for (OrderStream orderStream : list) {
            OrderStreamDto dto = BeanUtil.toBean(orderStream, OrderStreamDto.class);
            Result<StoreDto> result = personClient.getStoreById(orderStream.getStoreId());
            if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
            QueryWrapper<Stream> wrapper1=new QueryWrapper<>();
            Stream stream = streamService.getById(orderStream.getStreamId());
            dto.setStreamName(stream.getStreamName());
            StreamInfo streamInfo = streamInfoService.getById(orderStream.getStreamInfoId());
            dto.setStreamInfoName(streamInfo.getStreamInfoName());
            dto.setStoreName(result.getData().getStoreName());
            dtos.add(dto);
        }
        return Result.newListInstance(OrderStreamDto.class).setData(dtos).setMsg("获取订单流程成功");
    }

    /**
     * 按筛选条件分页获取用户订单流程详细信息
     * @param form 用户流程筛选条件
     * @param token
     * @return Page<OrderStreamDto> 选取页码的用户订单详细信息
     */
    @PostMapping("/orderStreamList.api")
    @ApiOperation("按筛选条件分页获取用户订单流程详细信息")
    public Result<Page<OrderStreamDto>> orderStreamList(@RequestBody OrderStreamFilterForm form, @RequestHeader String token){
        String storeAdminId = this.getStoreAdminId(token);
        String adminId = this.getAdminId(token);
        if(adminId==null&&storeAdminId==null) throw new WoniuException("非管理员",10001);
        OrderStreamFilterParam param = BeanUtil.toBean(form, OrderStreamFilterParam.class);
        QueryWrapper<OrderStream> wrapper = new QueryWrapper<>();
        if(param.getOrderStreamState2()!=null) wrapper.eq("order_stream_state2",param.getOrderStreamState2());
        if(param.getStreamInfoId()!=null) wrapper.eq("stream_info_id",param.getStreamInfoId());
        if(param.getStoreId()!=null) wrapper.eq("store_id",param.getStoreId());
        if(param.getOrderServiceNum()!=null) wrapper.eq("order_service_num",param.getOrderServiceNum());
        List<OrderStream> list = orderStreamService.list(wrapper);
        //分页,转dto
        long total = list.size();
        long pages=total%param.getPageSize()==0?total/param.getPageSize():total/param.getPageSize()+1;
        Page<OrderStreamDto> page=new Page<OrderStreamDto>();
        List<OrderStreamDto> dtos=new ArrayList<>();
        int i=0;
        for (OrderStream orderStream : list) {
            if(i<param.getPageNum()*param.getPageSize().intValue()&&i>=(param.getPageNum()-1)*param.getPageSize().intValue()){
                OrderStreamDto dto = BeanUtil.toBean(orderStream, OrderStreamDto.class);
                Result<StoreDto> result = personClient.getStoreById(orderStream.getStoreId());
                if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
                QueryWrapper<Stream> wrapper1=new QueryWrapper<>();
                Stream stream = streamService.getById(orderStream.getStreamId());
                dto.setStreamName(stream.getStreamName());
                StreamInfo streamInfo = streamInfoService.getById(orderStream.getStreamInfoId());
                dto.setStreamInfoName(streamInfo.getStreamInfoName());
                dto.setStoreName(result.getData().getStoreName());
                dtos.add(dto);
            }
            i=i+1;
        }
        page.setCurrent(param.getPageNum());
        page.setSize(param.getPageSize());
        page.setRecords(dtos);
        page.setTotal(total);
        page.setPages(pages);
        return Result.newPageInstance(OrderStreamDto.class).setData(page);
    }

    /**
     * 确认订单流程状态至完成
     * @param orderStreamId 订单流程Id
     * @return
     */
    @GetMapping("/sureOrderStreamComplete")
    @ApiOperation("确认订单流程状态至完成")
    @ApiImplicitParam(name = "orderStreamId",value = "订单流程编号")
    public Result<List<OrderStream>> sureOrderStreamComplete(Integer orderStreamId){
        //修改状态
        OrderStream order = orderStreamService.getById(orderStreamId);
        if(order.getOrderStreamState2()!=StaticData.ORDER_STREAM_STATE_NORMAL) throw new WoniuException("订单流程状态异常",10002);
        order.setOrderStreamState2(StaticData.ORDER_STREAM_STATE_COMPLETE);
        orderStreamService.updateById(order);
        //判断修改此状态后订单是否完结
        QueryWrapper<OrderStream> wrapper = new QueryWrapper<>();
        wrapper.eq("order_service_num",order.getOrderServiceNum());
        List<OrderStream> list = orderStreamService.list(wrapper);
        int size = list.stream().filter(o -> o.getOrderStreamState2() == StaticData.ORDER_STREAM_STATE_NORMAL).collect(Collectors.toList()).size();
        if(size<=0){
            //当订单流程中没有待处理的订单,此订单经过本次修改后将会完成
           orderClient.finishOrder(order.getOrderServiceNum());
        }
        return Result.newListInstance(OrderStream.class).setData(list);
    }
}

